package com.intramirror.product.controller;

import com.intramirror.core.common.exception.ValidateException;
import com.intramirror.core.common.response.ErrorResponse;
import com.intramirror.core.common.response.Response;
import com.intramirror.core.common.response.StatusCode;
import com.intramirror.product.entity.Promotion;
import com.intramirror.product.enums.PromotionRuleTypeEnum;
import com.intramirror.product.service.IProductService;
import com.intramirror.product.service.IPromotionService;
import com.intramirror.product.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;

@RestController
public class CampaignController {
    private final static Logger LOGGER = LoggerFactory.getLogger(CampaignController.class);

    @Autowired
    IPromotionService promotionService;

    @Autowired
    IProductService productService;

    @RequestMapping(value = "/campaign/active/{bannerId}", method = RequestMethod.GET)
    public Response getActiveCampaign(@PathVariable(value = "bannerId") Long bannerId) throws Exception {
        LOGGER.info("Get the active campaign for banner {}.", bannerId);
        //list集合
        List<Map<String, Object>> promotions = promotionService.getActivePromotionByBannerId(bannerId);
        return Response.status(StatusCode.SUCCESS).data(promotions);
    }

    @RequestMapping(value = "/campaign/starttime", method = RequestMethod.POST)
    public Response setCampaignActiveTime(@RequestBody Map<String, Object> param) {

        if (!param.containsKey("promotionId")) {
            throw new ValidateException(new ErrorResponse("promotionId is empty"));
        }

        if (!param.containsKey("startTime")) {
            throw new ValidateException(new ErrorResponse("startTime is empty"));
        }

        LOGGER.info("Set start time {} for promotionId {}.", param.get("startTime"), param.get("promotionId"));
        Promotion campaign = new Promotion();
        campaign.setPromotionId(Long.valueOf(param.get("promotionId").toString()));
        campaign.setStartTime(new Date(Long.valueOf(param.get("startTime").toString())));
        int resultCode = promotionService.setCampaignActiveTime(campaign);

        if (resultCode == 0) {
            return Response.status(StatusCode.FAILURE).data("同一个banner下不能有相同开始时间!");
        } else {
            return Response.status(StatusCode.SUCCESS).data("Ok");
        }
    }

    @RequestMapping(value = "/campaign/copy", method = RequestMethod.PUT)
    public Response copyCampaign(@RequestBody Map<String, Object> param) {
        Long bannerId = Long.valueOf(param.get("toBannerId").toString());
        String campaignName = (String) param.get("newCampaignName");
        Long campaignId = Long.valueOf(param.get("fromCampaignId").toString());
        Long startTime = Long.valueOf(param.get("startTime").toString());

        if (bannerId == null || campaignName == null || campaignId == null) {
            throw new ValidateException(new ErrorResponse("param is invalid"));
        }

        Promotion result = promotionService.copyCampaignToBanner(bannerId, campaignId, campaignName, startTime);
        if (result == null) {
            return Response.status(StatusCode.FAILURE).data("copy失败,同一个banner下不能有相同时间!");
        } else {
            return Response.status(StatusCode.SUCCESS).data(result);
        }

    }

    /**
     * 删除campaign
     * @param param
     * @return
     */
    @RequestMapping(value = "/campaign/delete", method = RequestMethod.POST)
    public Response deleteCampaign(@RequestBody Map<String, Object> param) {

        if (!param.containsKey("promotionId")) {
            throw new ValidateException(new ErrorResponse("promotionId is empty"));
        }

        if (!param.containsKey("bannerId")) {
            throw new ValidateException(new ErrorResponse("bannerId is empty"));
        }

        LOGGER.info("Set bannerId {} for campaign  {}.", param.get("bannerId"), param.get("promotionId"));

        Promotion campaign = new Promotion();
        campaign.setPromotionId(Long.valueOf(param.get("promotionId").toString()));
        campaign.setBannerId(Long.valueOf(param.get("bannerId").toString()));
        String msg = promotionService.deleteCampaign(campaign);

        if (msg.length() > 2) {
            return Response.status(StatusCode.FAILURE).data(msg);
        } else {
            return Response.status(StatusCode.SUCCESS).data(msg);
        }
    }

    /**
     * 新建promotion
     * @param param
     * @return
     */
    @RequestMapping(value = "/campaign/new", method = RequestMethod.POST)
    public Response newCampaign(@RequestBody Map<String, Object> param) {
        Long bannerId = Long.valueOf(param.get("bannerId").toString());
        String campaignName = (String) param.get("campaignName");
        Long startTime = Long.valueOf(param.get("startTime").toString());

        if (bannerId == null || bannerId == 0 || campaignName == null || campaignName.equals("") || startTime == 0 || startTime == null) {
            throw new ValidateException(new ErrorResponse("param is invalid"));
        }

        int resultCode = promotionService.newCampaignByBanner(bannerId, campaignName, startTime);
        if (resultCode == 0) {
            return Response.status(StatusCode.FAILURE).data("创建失败,同一个banner下不能有相同时间！");
        } else {
            return Response.status(StatusCode.SUCCESS).data("ok!");
        }
    }

    /**
     * 查询已设置规则的vendor
     * @param promotionId
     * @return
     */
    @GetMapping(value = "/campaign/boutique")
    public Response getPromotionBoutiqueHasRuleList(@RequestParam("promotionId") Long promotionId) {
        if (promotionId == null) {
            return Response.status(StatusCode.FAILURE).data("Param not positive.");
        }
        List<Map<String, Object>> data = promotionService.getPromotionBoutiqueHasRuleList(promotionId);
        return Response.status(StatusCode.SUCCESS).data(data);
    }

    /**
     * 查询promotion中vendor的每个season的商品数量
     * @param promotionId
     * @param vendorId
     * @return
     */
    @GetMapping(value = "/campaign/include/rule/count")
    public Response getPromotionIncludeRuleProductCount(@RequestParam("promotionId") Long promotionId, @RequestParam("vendorId") Long vendorId) {
        if (promotionId == null || vendorId == null) {
            return Response.status(StatusCode.FAILURE).data("Param not positive.");
        }
        Map<String, Object> params = new HashMap<>();
        params.put("promotionId", promotionId);
        params.put("vendorId", vendorId);
        List<Map<String, Object>> data = promotionService.getPromotionBoutiqueProductCountBySeason(params);
        return Response.status(StatusCode.SUCCESS).data(data);
    }

    /**
     * 查询promotion中vendor的season列表
     * @param promotionId
     * @param vendorId
     * @return
     */
    @GetMapping(value = "/campaign/boutique/season")
    public Response getPromotionVendorSeasonList(@RequestParam("promotionId") Long promotionId, @RequestParam("vendorId") Long vendorId) {
        if (promotionId == null || vendorId == null) {
            return Response.status(StatusCode.FAILURE).data("Param not positive.");
        }
        Map<String, Object> params = new HashMap<>();
        params.put("promotionId", promotionId);
        params.put("vendorId", vendorId);
        List<Map<String, Object>> data = promotionService.getPromotionBoutiqueSeason(params);
        return Response.status(StatusCode.SUCCESS).data(data);
    }

    /**
     * 查询promotion排除的商品数量
     * @param promotionId
     * @return
     */
    @GetMapping(value = "/campaign/exclude/product/count")
    public Response getPromotionExcludeProductCount(@RequestParam("promotionId") Long promotionId) {
        if (promotionId == null) {
            return Response.status(StatusCode.FAILURE).data("Param not positive.");
        }
        Map<String, Object> params = new HashMap<>();
        params.put("promotionId", promotionId);
        Integer count = promotionService.getPromotionBoutiqueExcludeProductCount(promotionId);
        return Response.status(StatusCode.SUCCESS).data(count);
    }

    @GetMapping(value = "/campaign/rule/{promotionId}")
    public Response editCampaignInfo(@PathVariable("promotionId") Long promotionId) {
        if (promotionId == null) {
            return Response.status(StatusCode.FAILURE).data("Param not positive.");
        }
        Map<String, Object> dataResult = promotionService.getPromotionById(promotionId);
        return Response.status(StatusCode.SUCCESS).data(dataResult);
    }

    /**
     * 删除vendor下的seasoncode
     * @param seasonCode
     * @return
     */
    @DeleteMapping("/campaign/delete/season/{seasonCode}/{vendor}/{ruleType}/{promotionId}")
    public Response deleteCampaignSeason(@PathVariable("seasonCode") String seasonCode, @PathVariable("vendor") Long vendor,
            @PathVariable("ruleType") String ruleType, @PathVariable("promotionId") Long promotionId) {
        LOGGER.info("Set seasonCode {} fro vendor {} ruleType{} promotionId {}.", seasonCode, vendor, ruleType, promotionId);
        PromotionRuleTypeEnum ruleTypeEnum;
        if ("include".equals(ruleType)) {
            ruleTypeEnum = PromotionRuleTypeEnum.INCLUDE_RULE;
        } else if ("exclude".equals(ruleType)) {
            ruleTypeEnum = PromotionRuleTypeEnum.EXCLUDE_RULE;
        } else {
            return Response.status(-1003).build();
        }
        Boolean result = promotionService.removePromotionRule(seasonCode, vendor, ruleTypeEnum, promotionId);
        return Response.status(StatusCode.SUCCESS).data(result);
    }

    /**
     * delete season
     * @param vendor
     * @param promotionId
     * @param seasonCode
     * @return
     */
    @DeleteMapping("/campaign/delete/vendor/season/{vendor}/{promotionId}/{seasonCode}")
    public Response deleteCampaignVendor(@PathVariable("vendor") Long vendor, @PathVariable("promotionId") Long promotionId,
            @PathVariable("seasonCode") String seasonCode) {
        LOGGER.info("Set   vendor {} for promotionId {} seasonCode{}.", vendor, promotionId, seasonCode);

        //delete vendor
        Boolean result = promotionService.removePromotionRuleByVendor(seasonCode, vendor, promotionId);
        return Response.status(StatusCode.SUCCESS).data(result);
    }

    @GetMapping(value = "/campaign/product/search")
    public Response searchProductList(@RequestParam("pageNo") Integer pageNo, @RequestParam("pageSize") Integer pageSize,
                                      @RequestParam("designerId") String designerId, @RequestParam("colorCode") String colorCode) {
        Map<String, Object> result = new HashMap<>();

        if (StringUtils.isEmpty(designerId)) {
            return Response.status(StatusCode.FAILURE).data("Designer id is empty！");
        }
        Map<String, Object> params = new HashMap<>();
        params.put("designerId", "%" + designerId + "%");
        if (StringUtils.isNotEmpty(colorCode)) {
            params.put("colorCode", colorCode);
        }
        int start = ((pageNo == null || pageNo < 1) ? 0 : (pageNo - 1) * pageSize);
        int limit = ((pageSize == null || pageSize < 1) ? 25 : pageSize);
        params.put("start", start);
        params.put("limit", limit);

        int total = productService.countProductByConditions(params);
        List<Map<String, Object>> list = new ArrayList<>();
        if (total > 0) {
            list = productService.getProductByConditions(params);
        }
        result.put("total", total);
        result.put("list", list);
        return Response.status(StatusCode.SUCCESS).data(result);
    }

    @GetMapping("/campaign/exclude/product/group/{vendorId}")
    public Response excludeProductGroup(@PathVariable("vendorId") Long vendorId, @RequestParam("orderBy") String orderBy) {
        return Response.status(StatusCode.SUCCESS).data(promotionService.getExcludeProductGroup(vendorId, orderBy));
    }

    @PostMapping("/campaign/exclude/product/group/add/{promotionId}/{tagId}")
    public Response addExcludeProductGroup(@PathVariable("promotionId") Long promotionId, @PathVariable("tagId") Long tagId) {
        boolean flag = promotionService.addExcludeProductGroup(promotionId, tagId);
        if (flag) {
            return Response.status(StatusCode.SUCCESS).data("Ok!");
        } else {
            return Response.status(StatusCode.FAILURE).data("product group 已存在！");
        }

    }

    @GetMapping("/campaign/exclude/product/group/vendor")
    public Response excludeProductGroupByVendor() {
        return Response.status(StatusCode.SUCCESS).data(promotionService.excludeProductGroupByVendor());
    }

    @PostMapping("/campaign/exclude/product/group/delete")
    public Response deleteExcludeProductGroup(@RequestParam("ids") List<Long> ids) {

        if (ids.size() < 1) {
            return Response.status(StatusCode.FAILURE).data("参数错误！");
        } else {
            return Response.status(StatusCode.SUCCESS).data(promotionService.deleteExcludeProductGroup(ids) > 0);
        }

    }

    @GetMapping("/campaign/exclude/product/group/get/{promotionId}")
    public Response getExcludeProductGroupByPromotionId(@PathVariable("promotionId") Long promotionId) {
        return Response.status(StatusCode.SUCCESS).data(promotionService.getExcludeProductGroupByPromotionId(promotionId));
    }

    @DeleteMapping("/campaign/delete/vendor/{vendor}/{promotionId}")
    public Response deleteCampaignVendor(@PathVariable("vendor") Long vendor, @PathVariable("promotionId") Long promotionId) {
        LOGGER.info("Set   vendor {} for promotionId {}.", vendor, promotionId);

        //delete vendor
        Boolean result = promotionService.removePromotionRuleByVendor(null, vendor, promotionId);
        return Response.status(StatusCode.SUCCESS).data(result);

    }
}
